﻿
using Castle.Core.Internal;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.Interface;
using Coldairarrow.Util;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;

namespace Coldairarrow.Business.Interface
{
    public class Rep_CostReductionInterfaceBusiness : Interface_BaseBusiness, IJob_Business, ITransientDependency
    {

        public List<OL_FilterDTO> Filters;
        public Base_InterfaceOption queryOption { get; set; }
        public Base_InterfaceOption insertOption { get; set; }
        public Base_InterfaceOption upDateOption { get; set; }
        public Base_InterfaceOption deleteOption { get; set; }
        public int NoQueryNum { get; set; }
        public Rep_CostReductionInterfaceBusiness()
        {
            this.InterfaceName = "采购降本报表";
            //获取字段的映射关系
            tableField = GetMapField("addRow");
            //索引字段
            Keys = GetKeys("addRow");
            indexFields.Add(Keys.Where(X => X.Type == "K").First().Field);
            //查询过滤条件
            Filters = new List<OL_FilterDTO>();
            //Filters.Add(
            //    new OL_FilterDTO() { ControlId = "674d08c59e0bc69bf1ab8162", DataType = 15, SpliceType = 1, FilterType = 13, Value = DateTime.Now.ToString("yyyy-MM-dd") }//只获取失效日期大于当前日期的
            //);

            //查询执行中的事件
            OnQueryEvent += InterfaceBusiness_OnQueryEvent;
            //查询执行前的事件
            BeforeQueryEvent += InterfaceBusiness_BeforeQueryEvent;
            //执行非查询请求中的事件
            OnNoQueryEvent += InterfaceBusiness_OnNoQueryEvent;

            //数据库连接
            ConString = JsonSettingHelper.GetSetting("Database:BaseDb:ConnectionString");
            SqlDb = (SqlServerHelper)DbHelperFactory.GetDbHelper(EFCore.Sharding.DatabaseType.SqlServer, ConString);

            //获取此接口的所有API信息
            this.interfaceOption = SqlDb.GetListBySql<Base_InterfaceOption>(@$"SELECT  * FROM  Base_InterfaceOption(NOLOCK) WHERE Name='{InterfaceName}' ");
            this.queryOption = this.interfaceOption.Where(o => o.OperateType == "getFilterRows").First();//查询API配置
            this.insertOption = this.interfaceOption.Where(o => o.OperateType == "addRow").First();//新增API配置
            this.upDateOption = this.interfaceOption.Where(o => o.OperateType == "editRow").First();//更行API配置
            this.deleteOption = this.interfaceOption.Where(o => o.OperateType == "deleteRow").First();//删除API配置
        }

        /// <summary>
        /// 执行非查询请求中时间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="noQueryEventArgs"></param>
        private void InterfaceBusiness_OnNoQueryEvent(object sender, NoQueryEventArgs noQueryEventArgs)
        {
            //API请求是否成功
            noQueryEventArgs.Success = noQueryEventArgs.Result["success"].ToString().ToBool();
        }


        /// <summary>
        /// 查询执行前的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="queryEventArgs"></param>
        private void InterfaceBusiness_BeforeQueryEvent(object sender, QueryEventArgs queryEventArgs)
        {
            //执行查询前添加过滤条件
            if (queryEventArgs.Page.Filters.IsNullOrEmpty() && !Filters.IsNullOrEmpty())
            {
                queryEventArgs.Page.Filters = Filters;
            }
        }

        /// <summary>
        /// 查询执行中的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="queryEventArgs"></param>
        private void InterfaceBusiness_OnQueryEvent(object sender, QueryEventArgs queryEventArgs)
        {
            //是否查询完成
            if (queryEventArgs.Result["data"]["rows"].ToList().Count == 0)
            {
                queryEventArgs.Page.Complete = true;
            }
            //向总行中添加新的行
            queryEventArgs.Rows.AddRange(queryEventArgs.Result["data"]["rows"].ToList());
            //获取总页数
            queryEventArgs.Page.Total = queryEventArgs.Result["data"]["total"].ToString().ToInt();
            //获取查询成功标志
            queryEventArgs.Success = queryEventArgs.Result["success"].ToString().ToBool();
        }

        /// <summary>
        /// 新增更新表
        /// </summary>
        public async void ExecuteInterface()
        {
            V_STK_INSTOCK_A v_STK_INSTOCK_A = new V_STK_INSTOCK_A();
            try
            {
                //SqlDb._conStrings[0] = insertOption.SourceLink;
                //SQLServer数据连接
                ConString = JsonSettingHelper.GetSetting("Database:BaseDb:K3ConnectionString");
                SqlDb = (SqlServerHelper)DbHelperFactory.GetDbHelper(EFCore.Sharding.DatabaseType.SqlServer, ConString);
                //Oracl数据连接
                ConString = JsonSettingHelper.GetSetting("Database:BaseDb:OracleConnectionString");
                OracleDb = (OracleHelper)DbHelperFactory.GetDbHelper(EFCore.Sharding.DatabaseType.Oracle, ConString);


                //获取采购入库单
                List<V_STK_INSTOCK_A> KD_STK_INSTOCKList = SqlDb.GetListBySql<V_STK_INSTOCK_A>(@$"SELECT * FROM {insertOption.SourceData}");
                //查询对应日期的
                //string fDate = KD_STK_INSTOCKList.Where(x => !x.FPOORDATE.IsNullOrEmpty()).OrderBy(x => x.FPOORDATE.ToDateTime()).First().FPOORDATE.ToDateTime().ToString("yyyy-MM-dd");
                //获取采购订单
                //List<V_PUR_POORDER> KD_PUR_POORDERList = SqlDb.GetListBySql<V_PUR_POORDER>(@$"SELECT * FROM V_PUR_POORDER(NOLOCK) WHERE  FDATE >= '{fDate}'");
                //获取OMS采购价目表
                List<PUR_PrdPrice> OMS_PrdPriceList = OracleDb.GetListBySql<PUR_PrdPrice>(@$"SELECT * FROM VIEW_WW_PUR_PRDPRICE");
                //获取源数据
                List<Rep_CostReduction> sourceData = new List<Rep_CostReduction>();//源数据集合


                foreach (var item1 in KD_STK_INSTOCKList)
                {
                    v_STK_INSTOCK_A = item1;
                    Rep_CostReduction rep = new Rep_CostReduction();
                    double basePrice = 0.0;
                    double price = !item1.FTAXPRICE.IsNullOrEmpty() ? item1.FTAXPRICE.ToDouble() : 0.0;
                    PUR_PrdPrice prdPrice = new PUR_PrdPrice();
                    List<PUR_PrdPrice> priceList = new List<PUR_PrdPrice>();

                    //获取基价
                    //如果订单存在价目表，直接获取单价
                    if (!item1.FPOORDATE.IsNullOrEmpty())
                    {

                        //获取一年前对应的价目表
                        priceList = OMS_PrdPriceList.Where(x => x.物料代码 == item1.FNUMBER && x.失效日期.ToDateTime() >= item1.FPOORDATE.ToDateTime().AddYears(-1) && x.生效日期.ToDateTime() <= item1.FPOORDATE.ToDateTime().AddYears(-1)).OrderBy(x => x.生效日期).ToList();

                        if (!priceList.IsNullOrEmpty() && priceList.Count > 0)
                        {
                            prdPrice = priceList.First();
                            basePrice = prdPrice.含税单价.ToDouble();
                        }
                        //如果不存在先获>=采购日期一年前日期的价目表
                        if (priceList.IsNullOrEmpty() || priceList.Count == 0)
                        {
                            priceList = OMS_PrdPriceList.Where(x => x.物料代码 == item1.FNUMBER && x.生效日期.ToDateTime() >= item1.FPOORDATE.ToDateTime().AddYears(-1) && x.生效日期.ToDateTime() <= item1.FPOORDATE.ToDateTime()).OrderBy(x => x.生效日期).ToList();
                            if (!priceList.IsNullOrEmpty() && priceList.Count > 0)
                            {
                                prdPrice = priceList.First();
                                basePrice = prdPrice.含税单价.ToDouble();
                            }
                        }
                        //如果>=不存在，再获取<=采购日期一年前日期的价目表
                        if (priceList.IsNullOrEmpty() || priceList.Count == 0)
                        {
                            priceList = OMS_PrdPriceList.Where(x => x.物料代码 == item1.FNUMBER && x.生效日期.ToDateTime() <= item1.FPOORDATE.ToDateTime().AddYears(-1)).OrderBy(x => x.生效日期).ToList();
                            if (!priceList.IsNullOrEmpty() && priceList.Count > 0)
                            {
                                prdPrice = priceList.Last();
                                basePrice = prdPrice.含税单价.ToDouble();
                            }
                        }
                    }
                    rep.State = price == 0 || basePrice == 0  ? "无原价/基价" : "正常";
                    rep.ReductionType = "基价";
                    rep.InvNumber = item1.FBILLNO;
                    rep.InvDate = item1.FDATE;
                    rep.InvQty = item1.FREALQTY;
                    rep.Number = item1.FNUMBER;
                    rep.Name = item1.FNAME;
                    rep.EffDate = !prdPrice.生效日期.IsNullOrEmpty() ? prdPrice.生效日期 : "";
                    rep.ExpDate = !prdPrice.失效日期.IsNullOrEmpty() ? prdPrice.失效日期 : "";
                    rep.Specification = item1.FSPECIFICATION;
                    rep.PurOrder = item1.FPOORDERNO;
                    rep.OrdeType = item1.FPOORDERTYPE;
                    rep.OrderDate = item1.FPOORDATE;
                    rep.Price = price.ToString("F6");//含税
                    rep.BasePrice = basePrice.ToString("F6");//含税
                    rep.Difference = price == 0 || basePrice == 0 ? "0" : (basePrice - price).ToString("F6");
                    rep.ReductionTotal = price == 0 || basePrice == 0 ? "0" : ((basePrice - price) * rep.InvQty.ToDouble()).ToString("F6");
                    rep.ID = item1.FENTRYID;
                    sourceData.Add(rep);
                }

                //是否存在重复项
                var g = sourceData.GroupBy(x => x.ID).Where(x => x.Count() > 1);






                //获取目标数据
                List<Rep_CostReduction> targetData = new List<Rep_CostReduction>();//目标据集合
                                                                                   //查询条件
                var fDate = sourceData.OrderBy(x => x.InvDate.ToDateTime()).First().InvDate.ToDateTime().ToString("yyyy-MM-dd");
                Filters.Clear();
                Filters.Add(
                new OL_FilterDTO() { ControlId = "67e60871c76bd298d7c6df1b", DataType = 15, SpliceType = 1, FilterType = 14, Value = fDate }//入库日期
            );
                targetData = await QueryAsync<Rep_CostReduction>(queryOption, tableField, SqlDb);
                if (this.State >= 0 && sourceData.Count > 0)
                {
                    //更新
                    #region
                    List<Rep_CostReduction> updataItem = sourceData.Intersect(targetData, new ComparerFromKeys<Rep_CostReduction>(Keys, "RowId")).ToList();//获取交集(更新项)
                    List<OL_RowDTO> updataData = ConvertOL_Row(updataItem, tableField);//需要更新的数据集合
                    ExecuteNoQuery<OL_RowDTO>(updataData, upDateOption, SqlDb);//执行更新
                    #endregion

                    //新增
                    #region
                    List<Rep_CostReduction> insertItem = sourceData.Except(targetData, new ComparerFromKey<Rep_CostReduction>(indexFields.First(), "RowId")).ToList();//获取源数据对目标数据的差集(新增项)
                    List<OL_RowDTO> insertData = ConvertOL_Row(insertItem, tableField);//需要新增的数据集合
                    ExecuteNoQuery<OL_RowDTO>(insertData, insertOption, SqlDb);//执行插入行
                    #endregion

                    //删除
                    #region
                    List<Rep_CostReduction> deleteItem = targetData.Except(sourceData, new ComparerFromKey<Rep_CostReduction>(indexFields.First(), "RowId")).ToList();//获取目标数对据源数据的差集(删除项)
                    //获取有重复的项
                    List<Rep_CostReduction> repeatItem = targetData.GroupBy(x => x.GetPropertyValue(indexFields.First())).Where(x => x.Count() > 1).Select(x => x.FirstOrDefault()).ToList();
                    //将重复的项也一起加入删除的列表
                    deleteItem.AddRange(repeatItem);
                    //筛选出删除列表中重复的项
                    var temp = deleteItem.GroupBy(x => x.GetPropertyValue(indexFields.First())).Where(x => x.Count() > 1).Select(x => x.FirstOrDefault()).ToList();
                    deleteItem.AddRange(temp);
                    List<OL_RowDTO> deleteData = ConvertOL_Row(deleteItem, tableField);//需要删除的数据集合
                    ExecuteNoQuery<OL_RowDTO>(deleteData, deleteOption, SqlDb);//执行删除行
                    #endregion
                }
                else
                {
                    throw new NotImplementedException("目标/源查询无数据无法执行接口!!");

                }
            }
            catch (Exception ex)
            {
                AddLog(SqlDb, ex.Message, InterfaceName, "erro", "");
            }
        }


        /// <summary>
        /// 将源数据根据字典映射关系转换成OL_RowDTO
        /// </summary>
        /// <typeparam name="T">源数据</typeparam>
        /// <param name="sourceData">源数据</param>
        /// <param name="map">Key为目标字段名称，Value为源字段名称</param>
        /// <returns></returns>
        public List<OL_RowDTO> ConvertOL_Row<T>(List<T> sourceData, Dictionary<string, string> map)
        {
            List<OL_RowDTO> list = new List<OL_RowDTO>();
            object rowId;
            foreach (var item in sourceData)
            {
                rowId = item.GetPropertyValue("RowId");
                //需要新增的数据
                OL_RowDTO row = new OL_RowDTO() { RowId = rowId.IsNullOrEmpty() ? null : rowId.ToString(), Controls = new List<Control>() };
                foreach (var c in map)
                {
                    //判断对象的字段是否存在
                    if (item.ContainsProperty(c.Value))
                    {
                        //存在则添加数据
                        row.Controls.Add(new Control() { ControlId = c.Key, Value = item.GetPropertyValue(c.Value) });
                    }
                }
                list.Add(row);
            }
            return list;
        }

        /// <summary>
        /// 任务
        /// </summary>
        public void Job()
        {
            ExecuteInterface();
        }
    }



}
